package com.yxhl.zoume.core.officialcar.fragment;


import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;

import com.afollestad.materialdialogs.MaterialDialog;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.yxhl.protobuf.MpvModel;
import com.yxhl.protobuf.OrderBizType;
import com.yxhl.zoume.R;
import com.yxhl.zoume.ZouMeApplication;
import com.yxhl.zoume.account.event.UserLoginEvent;
import com.yxhl.zoume.common.info.ToolbarType;
import com.yxhl.zoume.common.ui.fragment.BaseFragment;
import com.yxhl.zoume.core.specialcar.model.CarLocationMapEntrance;
import com.yxhl.zoume.core.officialcar.model.OfficialCarZMTimePicker;
import com.yxhl.zoume.core.officialcar.presenter.CreateOfficialCarOrderPresenter;
import com.yxhl.zoume.core.officialcar.presenter.InitializeOfficialCarPresenter;
import com.yxhl.zoume.core.officialcar.presenter.SingleWayQueryPresenter;
import com.yxhl.zoume.core.officialcar.activity.OfficialCarContainerActivity;
import com.yxhl.zoume.core.car.fragment.common.CarLocationMapFragment;
import com.yxhl.zoume.core.car.model.CarOtherPassengerEvent;
import com.yxhl.zoume.core.officialcar.view.CreateOfficialCarOrderView;
import com.yxhl.zoume.core.officialcar.view.SingleWayQueryView;
import com.yxhl.zoume.core.car.view.common.VehicleShowView;
import com.yxhl.zoume.core.func.map.ui.event.SelectedPOIEvent;
import com.yxhl.zoume.core.func.timepicker.presenter.ZMTimePickerPresenter;
import com.yxhl.zoume.core.func.timepicker.view.ZMTimePickerView;
import com.yxhl.zoume.data.http.model.account.ZMAccount;
import com.yxhl.zoume.di.component.car.DaggerOfficialCarComponent;
import com.yxhl.zoume.di.module.ActivityModule;
import com.yxhl.zoume.utils.AccountUtils;
import com.yxhl.zoume.utils.LOG;
import com.yxhl.zoume.utils.PromptUtils;
import com.yxhl.zoume.utils.ZMDialog;
import com.yxhl.zoume.utils.permission.PermissionHelper;

import java.util.List;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.BindViews;
import butterknife.OnClick;
import rx.Subscription;
import rx.functions.Action1;

/**
 * created by sugarya 16/08/10
 * 单程用车
 */
public class SingleWayOfficialCarFragment extends BaseFragment implements ZMTimePickerView, VehicleShowView,
        SingleWayQueryView, CreateOfficialCarOrderView {

    private static final String TAG = "SingleWayOfficialCarFrag";

    //widgets
    @BindView(R.id.tv_include_call_car_content)
    TextView mCallCarContentTv;

    @BindView(R.id.tv_include_call_others_right)
    TextView mCallOthersTv;

    @BindView(R.id.tv_include_get_in_location)
    TextView mGetInLocationTv;

    @BindView(R.id.tv_include_get_off_location)
    TextView mGetOffLocationTv;

    @BindView(R.id.tv_include_reservation_time)
    TextView mReservationTimeTv;

    @BindView(R.id.tv_fragment_single_way_price_distance_description)
    TextView mPriceDistanceDescriptionTv;

    @BindView(R.id.btn_fragment_single_way_confirm)
    Button mConfirmBtn;

    //箭头
    @BindViews({R.id.iv_fragment_single_way_official_car_previous, R.id.iv_fragment_single_way_official_car_next})
    List<ImageView> mArrowIvs;

    @BindView(R.id.hsv_fragment_single_way_official_car)
    HorizontalScrollView mVehicleHsv;

    @BindView(R.id.rg_fragment_single_way_container)
    RadioGroup mSingleWayContainerRg;


    //arguments
    @Inject
    ZMTimePickerPresenter mZMTimePickerPresenter;

    @Inject
    InitializeOfficialCarPresenter mInitializeOfficialCarPresenter;

    @Inject
    SingleWayQueryPresenter mSingleWayQueryPresenter;

    @Inject
    CreateOfficialCarOrderPresenter mCreateOfficialCarOrderPresenter;

    private OfficialCarContainerActivity mContainerActivity;
    private Subscription mGetInSubscription;
    private Subscription mGetOffSubscription;
    private Subscription mCallCarForOthersSubscription;


    private String mAccountName;
    private MaterialDialog loadingDialog;

    public SingleWayOfficialCarFragment() {
        // Required empty public constructor
    }

    public static SingleWayOfficialCarFragment newInstance() {
        SingleWayOfficialCarFragment fragment = new SingleWayOfficialCarFragment();
        return fragment;
    }

    private void onLoginSuccessRxBusEvent() {
        //登录成功
        getSubscription().add(toSubscription(UserLoginEvent.class,
                new Action1<UserLoginEvent>() {
                    @Override
                    public void call(UserLoginEvent userLoginEvent) {
                        initializeMobileNumberData();
                        if (mInitializeOfficialCarPresenter != null) {
                            mInitializeOfficialCarPresenter.queryOfficialCarDisplayData(OrderBizType.OFFICIAL_BUS_WAY);
                        }
                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        LOG.e(TAG, "throwable=" + throwable.toString());
                        onLoginSuccessRxBusEvent();
                    }
                }
        ));
    }

    private void onCallCarForOthersRxBusEvent() {
        mCallCarForOthersSubscription = toSubscription(CarOtherPassengerEvent.class,
                new Action1<CarOtherPassengerEvent>() {
                    @Override
                    public void call(CarOtherPassengerEvent carOtherPassengerEvent) {

                        handleCarOtherPassengerEvent(carOtherPassengerEvent, mCallCarContentTv, mAccountName);

                        //取消该订阅关系
                        if (mCallCarForOthersSubscription != null && !mCallCarForOthersSubscription.isUnsubscribed()) {
                            mCallCarForOthersSubscription.unsubscribe();
                        }
                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        LOG.e(TAG, "throwable=" + throwable.toString());
                        onCallCarForOthersRxBusEvent();
                    }
                }
        );
        //替他人叫车
        getSubscription().add(mCallCarForOthersSubscription);
    }

    private void onGetInRxBusEvent() {

        if (mGetInSubscription != null && !mGetInSubscription.isUnsubscribed()) {
            mGetInSubscription.unsubscribe();
        }

        //显示单程用车页
        mGetInSubscription = toSubscription(SelectedPOIEvent.class,
                new Action1<SelectedPOIEvent>() {
                    @Override
                    public void call(SelectedPOIEvent selectedPOIEvent) {
                        //显示单程用车页
                        ((OfficialCarContainerActivity) mActivity).displayOneFragment(
                                OfficialCarContainerActivity.FRAGMENT_SINGLE_WAY,
                                CarLocationMapEntrance.DEFAULT);

                        //数据处理
                        handleGetInSelectedPOIEvent(selectedPOIEvent, mGetInLocationTv);

                        checkLocationData();
                        //数据完整性检查
                        checkCompleteData();

                        //取消该订阅关系
                        if (mGetInSubscription != null && !mGetInSubscription.isUnsubscribed()) {
                            mGetInSubscription.unsubscribe();
                        }
                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        LOG.e(TAG, "throwable=" + throwable.toString());
                        onGetInRxBusEvent();
                    }
                }
        );
        getSubscription().add(mGetInSubscription);
    }


    private void onGetOffRxBusEvent() {
        //可能出现接收到别的下车的回调 点击先移除
        if (mGetInSubscription != null && !mGetInSubscription.isUnsubscribed()) {
            mGetInSubscription.unsubscribe();
        }
        mGetOffSubscription = toSubscription(SelectedPOIEvent.class,
                new Action1<SelectedPOIEvent>() {
                    @Override
                    public void call(SelectedPOIEvent selectedPOIEvent) {
                        //显示单程用车页
                        ((OfficialCarContainerActivity) mActivity).displayOneFragment(
                                SingleWayOfficialCarFragment.class.getSimpleName(),
                                CarLocationMapEntrance.DEFAULT);
                        //显示数据
                        handleGetOffSelectedPOIEvent(selectedPOIEvent, mGetOffLocationTv);

                        checkLocationData();
                        //数据完整性检查
                        checkCompleteData();

                        //取消该订阅关系
                        if (mGetOffSubscription != null && !mGetOffSubscription.isUnsubscribed()) {
                            mGetOffSubscription.unsubscribe();
                        }
                    }
                },
                new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        onGetOffRxBusEvent();
                    }
                }

        );
        getSubscription().add(mGetOffSubscription);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        onLoginSuccessRxBusEvent();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);
        mZMTimePickerPresenter.attachView(this);
        mInitializeOfficialCarPresenter.attachView(this);
        mSingleWayQueryPresenter.attachView(this);
        mCreateOfficialCarOrderPresenter.attachView(this);
        initializeClassFields();
        initializeListener();
        initializeStatusData();
        return view;
    }

    @Override
    public void onStart() {
        super.onStart();
        mInitializeOfficialCarPresenter.queryOfficialCarDisplayData(OrderBizType.OFFICIAL_BUS_WAY);
    }

    private void initializeClassFields() {
        mContainerActivity = (OfficialCarContainerActivity) mActivity;
    }

    private void initializeListener() {
        mSingleWayContainerRg.setOnCheckedChangeListener(new VehicleOnCheckedChangeLister());
    }

    private void initializeStatusData() {
        initializeMobileNumberData();
    }


    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (!hidden) {
            setupToolBar();
        }
    }

    /**
     * 默认显示用户手机号
     */
    private void initializeMobileNumberData() {
        ZMAccount account = AccountUtils.getInstance(mActivity).getAccount();
        if (account != null) {
            mAccountName = account.getAccountName();
            if (!TextUtils.isEmpty(mAccountName)) {
                if (mCallCarContentTv != null) {
                    mCallCarContentTv.setText(mAccountName);
                }
            }
        }
    }


    /**
     * 替他人叫车
     */
    @OnClick(R.id.tv_include_call_others_right)
    void onCallCarForOthersClick() {
        onCallCarForOthersRxBusEvent();
        ZouMeApplication.application.getAppComponent().navigator().navigateToCallCarForOthersActivity(mActivity);
    }

    /**
     * 上车地点
     */
    @OnClick(R.id.tv_include_get_in_location)
    void onGetInLocationClick() {
        onGetInRxBusEvent();

        if (PermissionHelper.checkLocationPermission(mActivity)) {
            ((OfficialCarContainerActivity) mActivity).displayOneFragment(
                    OfficialCarContainerActivity.FRAGMENT_CAR_LOCATION_MAP,
                    CarLocationMapEntrance.OFFICIAL_CAR_SINGLE_WAY_GET_IN);
        } else {
            PermissionHelper.takeLocationPermission(this, PermissionHelper.REQUEST_CODE_OFFICIAL_CAR_SINGLE_WAY_GET_IN_LOCATION);
        }
    }

    /**
     * 下车地点
     */
    @OnClick(R.id.tv_include_get_off_location)
    void onGetOffLocationClick() {
        onGetOffRxBusEvent();

        if (PermissionHelper.checkLocationPermission(mActivity)) {
            ((OfficialCarContainerActivity) mActivity).displayOneFragment(
                    OfficialCarContainerActivity.FRAGMENT_CAR_LOCATION_MAP,
                    CarLocationMapEntrance.OFFICIAL_CAR_SINGLE_WAY_GET_OFF);
        } else {
            PermissionHelper.takeLocationPermission(this, PermissionHelper.REQUEST_CODE_OFFICIAL_CAR_GET_OFF_LOCATION);
        }
    }

    /**
     * 出行时间
     */
    @OnClick(R.id.tv_include_reservation_time)
    void onReservationTimeClick() {
        mZMTimePickerPresenter.showZMTimePicker(OfficialCarZMTimePicker.class);
    }

    /**
     * 上一个
     */
    @OnClick(R.id.iv_fragment_single_way_official_car_previous)
    void onPreviousVehicleClick() {
        mVehicleHsv.smoothScrollBy(-mInitializeOfficialCarPresenter.getVehicleTotalDisplayWith(), 0);
    }

    /**
     * 下一个
     */
    @OnClick(R.id.iv_fragment_single_way_official_car_next)
    void onNextVehicleClick() {
        mVehicleHsv.smoothScrollBy(mInitializeOfficialCarPresenter.getVehicleTotalDisplayWith(), 0);
    }

    /**
     * 下单
     */
    @OnClick(R.id.btn_fragment_single_way_confirm)
    void onSubmitOrderClick() {
        mCreateOfficialCarOrderPresenter.createOfficialCarOrder(OrderBizType.OFFICIAL_BUS_WAY);
    }

    //时间选择器回调
    @Override
    public void renderZMTimePickerOptionSelectResult(String zmTimePickerSimpleName, String options1, String options2, String options3) {
        LOG.e(TAG, "options1=" + options1 + "options2=" + options2 + "options3=" + options3);
        mCreateOfficialCarOrderPresenter.handleZMTimePickerSelectResult(options1, options2, options3);

        mReservationTimeTv.setText(options1 + " " + options2 + " " + options3);
        checkCompleteData();
    }

    //车辆类型 查询回调
    @Override
    public void renderVehicleModelDataOnSuccess(List<MpvModel> vehicleModelsList) {
        mInitializeOfficialCarPresenter.initializeArrowShow(mArrowIvs);
        mInitializeOfficialCarPresenter.initializeVehicleShowByOnline(mSingleWayContainerRg);
    }

    @Override
    public void renderVehicleModelDataOnFailure(String msg) {
        PromptUtils.showShort(mActivity, msg);
    }

    @Override
    public void renderVehicleModeDataOnError(String errorMsg) {
        PromptUtils.showShort(mActivity, getString(R.string.net_error));
    }

    //价格/距离 查询回调
    @Override
    public void renderQueryPriceAndDistanceOnSuccess(String description) {
        if (!TextUtils.isEmpty(description)) {
            mPriceDistanceDescriptionTv.setText(description);
        }
    }

    @Override
    public void renderQueryPriceAndDistanceOnFailure(String failureMsg) {
        PromptUtils.showShort(mActivity, failureMsg);
    }

    @Override
    public void renderQueryPriceAndDistanceOnError(String errorMsg) {
        PromptUtils.showShort(mActivity, getString(R.string.net_error));
    }

    //下单回调
    @Override
    public void renderOfficialCarOrderOnSuccess(String orderId) {
        ZouMeApplication.application.getAppComponent().navigator().navigateToOfficialCarScheduleActivity(mActivity, orderId);
    }

    @Override
    public void renderOfficialCarOrderOnFailure(String failureMsg) {
        PromptUtils.showShort(mActivity, failureMsg);
        showWaitingDialog(false);
    }

    @Override
    public void renderOfficialCarOrderOnError(String errorMsg) {
        PromptUtils.showShort(mActivity, getString(R.string.net_error));
    }

    @Override
    public void showWaitingDialog(boolean needShow) {
        if (needShow) {
            loadingDialog = ZMDialog.getLoadingDialog(mActivity);
        } else {
            if (loadingDialog != null) {
                loadingDialog.dismiss();
            }
        }
    }

    /**
     * 检验查询价格/距离
     */
    private void checkLocationData() {

        String getInLocation = mGetInLocationTv.getText().toString();
        String getOffLocation = mGetOffLocationTv.getText().toString();

        if (TextUtils.isEmpty(getInLocation)) {
            return;
        }

        if (TextUtils.isEmpty(getOffLocation)) {
            return;
        }

        boolean selected = mSingleWayContainerRg.getCheckedRadioButtonId() > -1;
        if (mSingleWayQueryPresenter != null && selected) {
            mSingleWayQueryPresenter.queryPriceAndDistance(OrderBizType.OFFICIAL_BUS_WAY);
        }
    }

    /**
     * 检验数据完整性
     */
    private void checkCompleteData() {
        String mobileNumber = mCallCarContentTv.getText().toString();
        String getInLocation = mGetInLocationTv.getText().toString();
        String getOffLocation = mGetOffLocationTv.getText().toString();
        String ReservationTime = mReservationTimeTv.getText().toString();
        int checkedRadioButtonId = mSingleWayContainerRg.getCheckedRadioButtonId();

        if (TextUtils.isEmpty(mobileNumber)) {
            return;
        }

        if (TextUtils.isEmpty(getInLocation)) {
            return;
        }

        if (TextUtils.isEmpty(getOffLocation)) {
            return;
        }

        if (TextUtils.isEmpty(ReservationTime)) {
            return;
        }

        if (checkedRadioButtonId < 0) {
            return;
        }

        mConfirmBtn.setEnabled(true);
    }

    /**
     * 处理事件
     *
     * @param carOtherPassengerEvent
     * @param callCarContentTv
     * @param accountName
     */
    private void handleCarOtherPassengerEvent(CarOtherPassengerEvent carOtherPassengerEvent, TextView callCarContentTv, String accountName) {
        String otherMobile = carOtherPassengerEvent.getPassengerMobile();
        boolean needSendMsg = carOtherPassengerEvent.isNeedSendMsg();

        if (!TextUtils.isEmpty(otherMobile)) {
            if (callCarContentTv != null) {
                callCarContentTv.setText(otherMobile);
            }
            mCreateOfficialCarOrderPresenter.setOtherMobile(otherMobile);
            mCreateOfficialCarOrderPresenter.setNeedSendMsg(needSendMsg);
            if (!otherMobile.equalsIgnoreCase(accountName)) {
                mCreateOfficialCarOrderPresenter.setNeedCallCarForOthers(true);
            } else {
                mCreateOfficialCarOrderPresenter.setNeedCallCarForOthers(false);
            }
        }
    }

    /**
     * 处理上车 回调事件
     *
     * @param selectedPOIEvent
     * @param getInLocationTv
     */
    private void handleGetInSelectedPOIEvent(SelectedPOIEvent selectedPOIEvent, TextView getInLocationTv) {
        PoiItem poiItem = selectedPOIEvent.getPoiItem();
        if (poiItem != null) {
            String title = poiItem.getTitle();
            getInLocationTv.setText(title);

            //查询距离和价格 准备数据
            LatLonPoint latLonPoint = poiItem.getLatLonPoint();
            if (latLonPoint != null) {
                double latitude = latLonPoint.getLatitude();
                double longitude = latLonPoint.getLongitude();
                mSingleWayQueryPresenter.setLat(String.valueOf(latitude));
                mSingleWayQueryPresenter.setLng(String.valueOf(longitude));

                mCreateOfficialCarOrderPresenter.setStartLocation(title);
                mCreateOfficialCarOrderPresenter.setLat(String.valueOf(latitude));
                mCreateOfficialCarOrderPresenter.setLng(String.valueOf(longitude));
            }
        }
    }

    /**
     * 处理下车 回调事件
     *
     * @param selectedPOIEvent
     * @param getOffLocationTv
     */
    private void handleGetOffSelectedPOIEvent(SelectedPOIEvent selectedPOIEvent, TextView getOffLocationTv) {
        PoiItem poiItem = selectedPOIEvent.getPoiItem();
        if (poiItem != null) {
            String title = poiItem.getTitle();
            getOffLocationTv.setText(title);
            //查询距离和价格 准备数据
            LatLonPoint latLonPoint = poiItem.getLatLonPoint();
            if (latLonPoint != null) {
                double latitude = latLonPoint.getLatitude();
                double longitude = latLonPoint.getLongitude();
                mSingleWayQueryPresenter.setEndLat(String.valueOf(latitude));
                mSingleWayQueryPresenter.setEndLng(String.valueOf(longitude));

                mCreateOfficialCarOrderPresenter.setEndLocation(title);
                mCreateOfficialCarOrderPresenter.setEndLat(String.valueOf(latitude));
                mCreateOfficialCarOrderPresenter.setEndLng(String.valueOf(longitude));
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (grantResults != null && grantResults.length > 0) {
            switch (requestCode) {
                case PermissionHelper.REQUEST_CODE_OFFICIAL_CAR_SINGLE_WAY_GET_IN_LOCATION:
                    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        mContainerActivity.displayOneFragment(
                                CarLocationMapFragment.class.getSimpleName(),
                                CarLocationMapEntrance.OFFICIAL_CAR_SINGLE_WAY_GET_IN);
                    } else {
                        PromptUtils.showShort(mActivity, getString(R.string.permission_location_deny_message));
                    }
                    break;
                case PermissionHelper.REQUEST_CODE_OFFICIAL_CAR_GET_OFF_LOCATION:
                    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        mContainerActivity.displayOneFragment(
                                CarLocationMapFragment.class.getSimpleName(),
                                CarLocationMapEntrance.OFFICIAL_CAR_SINGLE_WAY_GET_OFF);
                    } else {
                        PromptUtils.showShort(mActivity, getString(R.string.permission_location_deny_message));
                    }
                    break;
            }
        }
    }

    @Override
    protected void initializeInjector() {
        DaggerOfficialCarComponent
                .builder()
                .appComponent(getAppComponent())
                .activityModule(new ActivityModule(mActivity))
                .build()
                .inject(this);
    }

    @Override
    protected int getLayoutResId() {
        return R.layout.fragment_single_way_official_car;
    }

    @Override
    protected void setupToolBar() {
        if (mActivity instanceof OfficialCarContainerActivity) {
            OfficialCarContainerActivity containerActivity = ((OfficialCarContainerActivity) mActivity);
            containerActivity.changeToolbarInto(ToolbarType.SINGLE_WAY);
        }
    }

    /**
     * 车辆类型选择
     */
    class VehicleOnCheckedChangeLister implements RadioGroup.OnCheckedChangeListener {

        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            RadioButton checkedRb = (RadioButton) group.findViewById(checkedId);
            if (checkedRb != null) {
                String vehicleType = (String) checkedRb.getTag();
                mCreateOfficialCarOrderPresenter.setVehicleType(vehicleType);
                mSingleWayQueryPresenter.setVehicleType(vehicleType);
                checkLocationData();
                checkCompleteData();
            }
        }
    }
}
